#include<sys/socket.h>
#include<sys/epoll.h>

#include "ThreadPool.h"

int exitPipe[2];
void handler(int signum)
{
	printf("signum = %d\n", signum);
	write(exitPipe[1], "1", 1);
}

int main(int argc, const char *argv[])
{
	ARGS_CHECK(argc, 4);

	pipe(exitPipe);
	if (fork()) { // Parent process
		close(exitPipe[0]);
		signal(SIGUSR1, handler);
		wait(NULL);
		printf("Parent is going to exit!\n");
		exit(0);
	}
	close(exitPipe[1]);

	ThreadPool threadpool;
	threadPool_init(&threadpool, atoi(argv[3]));
	_startWorker(&threadpool);
	int sockfd = tcp_init(argv[1], argv[2]);
	ERROR_CHECK(sockfd, -1, "socket create error");
	int epfd = epoll_create(1);
	ERROR_CHECK(epfd, -1, "epoll create error");

	epollAdd(epfd, sockfd);
	epollAdd(epfd, exitPipe[0]); // 监听退出管道

	struct epoll_event readyset[1024];
	while (1) {
        int readyNum = epoll_wait(epfd, readyset, 1024, -1);
        for (int i = 0; i < readyNum; i++) {
            int currentFd = readyset[i].data.fd;
            if (currentFd == sockfd) {
                // 处理新连接
                int netfd = accept(sockfd, NULL, NULL);
                printf("netfd : %d\n", netfd);
                epollAdd(epfd, netfd);
            } else if (currentFd == exitPipe[0]) {
                // 处理退出信号
                printf("Child is going to exit!\n");
                pthread_mutex_lock(&threadpool._mLock);
                threadpool._exitFlag = 1;
                // 清理未处理的任务
                while (!_taskQueue_is_empty(&threadpool._taskQueue)) {
                    task_t *task = _taskQueue_front(&threadpool._taskQueue);
                    _taskQueue_deque(&threadpool._taskQueue);
                    close(task->_clientFd);
                    free(task);
                }
                pthread_cond_broadcast(&threadpool._mCond);
                pthread_mutex_unlock(&threadpool._mLock);
                // 等待所有线程退出
                for (int i = 0;i < threadpool._tidArr._worker_num;++i) {
                    pthread_join(threadpool._tidArr._arr[i],NULL);
                }
                // 关闭资源
                close(sockfd);
                close(epfd);
                printf("Child has exited!\n");
                exit(0);
            } else {
                // 处理客户端数据
                int netfd = currentFd;
                train_t cmdTrain;
                ssize_t ret = recv(netfd, &cmdTrain,sizeof(train_t), 0);
                if (ret <= 0) {
                    // 客户端断开或错误
                    epollDel(epfd, netfd);
                    close(netfd);
                    continue;
                }
                // 创建任务
                task_t *newTask =(task_t *)malloc(sizeof(task_t));
                newTask->_clientFd = netfd;
                newTask->_cmdType = cmdTrain._cmdType;
                strncpy(newTask->_data, cmdTrain._data,sizeof(newTask->_data));
                newTask->_data[sizeof(newTask->_data) - 1] ='\0';
                // 加入队列
                pthread_mutex_lock(&threadpool._mLock);
                _taskQueue_enque(&threadpool._taskQueue, newTask);
                pthread_cond_broadcast(&threadpool._mCond);
                pthread_mutex_unlock(&threadpool._mLock);
                }
            }
    }
	return 0;
}